package fr.perso.ppo.springintegration.business;

import java.util.Date;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.exception.ws.BusinessException;
import com.exception.ws.TechnicalException;
import com.google.common.base.Preconditions;

import fr.mycompany.rce.ws.v1_0.BK90L00Output;
import fr.mycompany.rce.ws.v1_0.RCEWsConnector;
import fr.perso.ppo.springintegration.domain.PaiementGDPA;

@Component("rceWsService")
public class RceWsServiceImpl implements InitializingBean, RceWsService {

	private static Logger log = LoggerFactory.getLogger(RceWsServiceImpl.class);
	private static Logger logWs = LoggerFactory.getLogger("logWs");

	@Autowired
	private RCEWsConnector connector;

	public void afterPropertiesSet() throws Exception {
		Preconditions.checkNotNull(connector, "the connector to WS should not be null");

	}

	/**
	 * {@inheritDoc}
	 * 
	 * @see fr.perso.ppo.springintegration.business.RceWsService#service(fr.perso.ppo.springintegration.domain.PaiementGDPA)
	 */
	public PaiementIntegrationMessage service(PaiementGDPA paiement) throws Exception {

		BK90L00Output response = null;
		PaiementIntegrationMessage msg = new PaiementIntegrationMessage();
		// TODO rajouter un logger dedie aux appels SOAP (format a definir) =>
		// supervision
		
		long startDate = System.currentTimeMillis();

		try {
			log.info("=====================>call RCE ws for {}",paiement.getCDENC());	
			response = connector.callMethod(paiement.getCDENC());
			log.info("=====================> fin call RCE ws for {} in {} ms",paiement.getCDENC(),System.currentTimeMillis()-startDate);
			parseResponse(response);
			msg.setStatut("OK");
		} catch (TechnicalException e) {
			log.error("Erreur lors de appel WS ", e);
			msg.setStatut("Technical KO");
			// TODO should try n times (n=3) with a delay that gets bigger each
			// time
			// see Spring batch + Spring integration or use message broker redlivery policy
			throw e;
		} catch (BusinessException e) {
			log.warn("Erreur fonctionnelle los de appel WS", e);
			// TODO ajout de log4j extra pour limiter le fichier de log
			// applicative a la root cause => pas de stacktrace dans ce cas.
			msg.setStatut("Business KO");
		} finally {
			long durationInMillis = System.currentTimeMillis() - startDate;
			log.info("RCE bk90L00 ws  invocation duration {} ms", durationInMillis);
			logWs.info("RCE bk90L00 ws; {};{}", (new Object[] { msg.getStatut(), durationInMillis }));
		}

		msg.setResponse(StringUtils.abbreviate(response.toString(), 500) );
		msg.setPaiementId(String.valueOf(paiement.getId()));
		msg.setTrackingDate(new Date());

		return msg;
	}

	private void parseResponse(BK90L00Output response) {
		// TODO Auto-generated method stub

	}

}
